package com.jlf.starter.advice.reactive.conf;

import com.jlf.starter.advice.reactive.OutputAdvice;
import com.jlf.starter.advice.reactive.excepton.GlobalErrorAttributes;
import com.jlf.starter.advice.reactive.excepton.GlobalErrorWebExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
import org.springframework.web.reactive.result.method.annotation.ResponseBodyResultHandler;
import org.springframework.web.reactive.result.view.ViewResolver;

/**
 * 自动配置
 * ModifyResponseBodyGatewayFilterFactory
 *
 * @author wujr
 * 2023/8/2
 * @version 1.0
 * 【变更历史】
 * [wujr 2023/8/2 1.0 新增]
 */
@Slf4j
@Configuration
@AutoConfigureBefore(ErrorWebFluxAutoConfiguration.class)
public class AdviceAutoConfiguration {
    @Bean
    public ResponseBodyResultHandler resultHandler(@Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry,
                                            ServerCodecConfigurer serverCodecConfigurer,
                                            @Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) {
        return new OutputAdvice(serverCodecConfigurer.getWriters(), contentTypeResolver, reactiveAdapterRegistry);
    }

//    @Bean
//    public OutputAspect responseWrapper(){
//        return new OutputAspect();
//    }

    @Bean
    public GlobalErrorAttributes errorAttributes(){
        return new GlobalErrorAttributes();
    }

    @Bean
    @Order(-2)
    public GlobalErrorWebExceptionHandler errorHandler(GlobalErrorAttributes errorAttributes,
                                                       WebProperties webProperties,
                                                       ServerProperties serverProperties,
                                                       ApplicationContext applicationContext,
                                                       ObjectProvider<ViewResolver> viewResolvers,
                                                       ServerCodecConfigurer serverCodecConfigurer){
        GlobalErrorWebExceptionHandler handler = new GlobalErrorWebExceptionHandler(errorAttributes,
                webProperties.getResources(), serverProperties.getError(), applicationContext);
        handler.setViewResolvers(viewResolvers.orderedStream().toList());
        handler.setMessageWriters(serverCodecConfigurer.getWriters());
        handler.setMessageReaders(serverCodecConfigurer.getReaders());
        return handler;
    }
}
